#!/usr/bin/perl
#
# Process an user update that comes as a Web form
# This is the admin version 
#

use Counter;
use CounterCGI;
use FileTable;
use POSIX;
use Validate::Persons;
use Counter::CGI;
use CGI::Carp;
use ErrorForm;
use Encode;
require "isemail.pl";

$] > 5.008 && binmode(STDOUT, ":utf8"); # set web page output to utf-8

open(LOG, ">>logs/eventlog");
print LOG scalar(localtime), " userupdate.cgi(i18n)\n";
$| = 1; # fast flush (debug)

$q = new Counter::CGI;

for $name ($q->param()) {
    if ($] > 5.008 && !Encode::is_utf8($q->param($name))) {
        #warn "Perl version >5.008";
        $entry{$name} = Encode::decode("utf-8", $q->param($name));
    } else {
        #warn "Perl version <=5.008";
        $entry{$name} = $q->param($name);
    }
}

# Try to process command
$users = Counter::open(O_RDWR);
$persons = FileTable::open("db/persons", O_RDWR);

($key = $entry{key}) =~ s/-.*//;
$user = $users->get($key);

if (!$user) {
    die "ERROR: No user record for $key ($entry{$key})\n";
}

$otheruser = $users->getbyemail($entry{sendreplyto});
if ($otheruser) {
    if ($otheruser->key() ne $user->key()) {
	my $otherkey = $otheruser->key();
	warn "Mismatch: User->key:", $user->key, ", otheruser->key:", $otheruser->key(), "!\n";
	print <<EoF;
Content-type: text/html; charset="utf-8"

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>
EoF
CounterCGI::pagehead(__("Linux Counter Admin Update: Collision"));
print "<body bgcolor=white>\n";
CounterCGI::pagetop($q);
print "\n<h1><img src=\"/gifs/Logo-small.png\" alt=\"" . __("Linux Counter Logo") . "\">";
print __("Collision"), "</h1>\n";

print __("The email"), " $entry{sendreplyto} ", __("belongs to entry"), " <a href=\"/cgi-bin/adm/display-person.cgi?user=$otherkey\">#$otherkey</a>.\n<p>\n", __("The current record is"), " #$key. ", __("Merge them using the \"Merge\" field on the person display page, if that is the Right Thing.");
CounterCGI::pagebottom();
print "\n</body>\n</html>";
       exit(0);
    }
}

#
# Start off the HTML. Anything that happens is recorded in a comment
#
print "Content-type: text/html; charset=\"utf-8\"\n\n";

print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n\n";

print "<html>";
CounterCGI::pagehead(__("Linux Counter Admin Update Ack"));
print "<body bgcolor=white>\n";
CounterCGI::pagetop($q);
print "\n<h1><img src=\"/gifs/Logo-small.png\" alt=\"" . __("Linux Counter Logo") . "\">";
print __("Linux Counter Admin Update Ack"). "</h1>\n";
print "<!--\n"; # Comment to hide the trace stuff

for $key (sort(keys(%entry))) {
    print "$key: $entry{$key}\n";
}

# Removed - this is the ADMIN userupdate
#if ($user->{key} ne $entry{key}) {
#    print "SECURITY ERROR: Key doesn't match\n";
#    warn "SECURITY ERROR: Key doesn't match\n";
#    $userkey = $user->{key};
#    warn "Is $entry{key} should have been $userkey\n";
#    print LOG "userupdate: $entry{$key} is not $userkey\n";
#    exit 1;
#}
push(@sendackto, $user->{email});

# Find action. I don't like this, but it's what works...
if ($entry{"delete"}) {
    print __("Action: DELETE"), "\n";
    $person = $persons->get($key);
    if ($user && $person) {
	$person->delete;
	delete $user->{person};
	$user->store;
	print LOG "Person $key deleted by $ENV{REMOTE_USER}\n";
    } elsif ($user && !$person) {
	warn "Deleting deleded person $key\n";
print "-->\n";
print __("Entry has already been deleted. Nothing more needs to be done.");
CounterCGI::pagebottom();
print "\n</body>\n</html>";
	exit 0;
    } else {
	warn "User or person not found for $key\n";
	exit 1;
    }
    # NOTE: we do NOT send email on admin delete
    print "-->\n";
print "<h1>", __("This entry has been deleted"), "</h1>\n";
print __("This person info has been deleted from the Linux Counter. It will not be included in the count of Linux users.");
print "\n<p>\n";
print __("NOTE: The user has NOT been informed.");
print "\n<p>\n";
CounterCGI::pagebottom();
print "\n</body>\n</html>";

} else {
    if ($entry{"enter"}) {
	warn "adm/userupdate action ENTER\n";
    } else {
	warn "adm/userupdate action DEFAULT\n";
    }
    print __("Action: ENTER"), "\n";
    $dosendemail = 0; # By default, don't send email on update
    $user = $users->get($key);
    if (!$user) {
	warn "userupdate: key $key not found\n";
	print LOG "No update on $key - not found in users\n";
	print __("key"), " $key ", __("not found in users"), "!\n";
	# NOTE: Printout of error form is missing.....
	exit 1;
    } elsif ($entry{sendreplyto} && $entry{sendreplyto} ne $user->{email}
	     || $entry{comment} && $entry{comment} ne $user->{comment} ) {
	warn "adm/userupdate changing USER record\n";
	if ($entry{sendreplyto} && $entry{sendreplyto} ne $user->{email}) {
	    print __("Changing USER email to"), " $entry{sendreplyto}\n";
	    push(@sendackto, $entry{sendreplyto});
	    print LOG "User ", $user->key,
		 " email changed to $entry{sendreplyto}\n";

	    $user->{email} = $entry{sendreplyto};
	    $dosendemail = 1;
	}
	$user->{comment} = $entry{comment};
	addadmin($user);
	# NOTE: No guard against the error of setting it to someone
	# else's email....store will crash...
	# but this should have been trapped earlier in the script.
	$user->store;
    }
    # An user may want to add himself even if he's not present
    $person = $persons->get($key, O_CREAT);
    
    for $field ($persons->fields) {
	if ($entry{$field}) {
	    if ($person->{$field}) {
		if ($person->{$field} ne $entry{$field}) {
		    my $uf = $person->{$field};
		    print __("Changing"), " $field ", __("from"), " $uf ", __("to"), " $entry{$field}\n";
		}
	    } else {
		print __("Adding"), " $field: $entry{$field}\n";
	    }
	} elsif ($person->{$field}) {
	    print __("Deleting"), " $field\n";
	}
	$person->{$field} = $entry{$field};
    }
    # Clean up the record
    my $recordempty = 1;
    for $field ($person->fields) {
	if ($person->{$field} eq "") {
	    delete $person->{$field};
	} else {
	    $recordempty = 0;
	}
    }
    if (!$recordempty) {
	addadmin($person);
	print LOG "Person $key updated by $ENV{REMOTE_USER}\n";
	$person->store;
	if ($user->{person} ne "y") {
	    $user->{person} = "y";
	    $user->store;
	}
    } else {
	print LOG "Empty person record not stored for $key\n";
    }
    # E-mail ack of change
    if ($dosendemail) {
	# FIXME: No check that sendackto is legal email
	$hasnot = __("has");
	system("tools/send18mail", "$key", @sendackto);
    }
    print "-->\n"; # End comment around script trace    
    $sendackto = join(" and ", @sendackto);
print "\n<h1>", __("The record is updated"), "</h1>\n";
print "<p>\n";
    if ($dosendemail) {
print __("An acknowledge message"), " ", $hasnot, " ", __(" been sent to"), " $sendackto";
print "\n<p>\n";
    }
print __("If there are any problems with the counter, don't hesitate to contact"), " Help&#x40;Counter.li.org";
print "\n<p>\n";
# Mext line SHOULD be variable, but that doesn't work :-(
print "<a href=\"https://i18n.counter.li.org/adm/update.php\"><img src=\"/gifs/shark-gull.gif\"> ", __(" Back to update page"), "</a>\n<br>\n";
print "<a href=\"/index.php\"><img src=\"/gifs/shark-gull.gif\"> ", __("Back to main page"), "</a>\n<br>\n";
print "<a href=\"/cgi-bin/adm/display-person.cgi?user=$key\"><img src=\"/gifs/shark-gull.gif\"> ", __("Back to user record"), "</a>\n";
CounterCGI::pagebottom();
print "\n</body>\n</html>";
} # end of ENTER branch of update

exit 0;

# Add admin fields - recdate and method - to a record
sub addadmin {
    my $record = shift;

    $record->{recdate} = scalar(localtime);
    $record->{method} = "admin";
    $record->{ident} = "script=$0 ip=$ENV{REMOTE_ADDR} user=$ENV{REMOTE_USER}";
}

